import callFunctionUtil   from './vk-unicloud-callFunctionUtil'
import localStorage       from './function/vk.localStorage'
import navigate           from './function/vk.navigate' 
import storeMixin         from './mixin/mixin'
import modal              from './function/modal'
var vk={
    ...localStorage,
    callFunctionUtil,
    userCenter:{}, 
    callFunction:     callFunctionUtil.callFunction,
    getToken:         callFunctionUtil.getToken,
    checkToken:       callFunctionUtil.checkToken,
    uploadFile:       callFunctionUtil.uploadFile,
    getConfig:        callFunctionUtil.getConfig,
    emitRefreshToken: callFunctionUtil.emitRefreshToken,
    onRefreshToken:   callFunctionUtil.onRefreshToken,
    offRefreshToken:  callFunctionUtil.offRefreshToken,
    navigate,
    myfn:{
        
    }, 
    // 保留当前页面,并进行页面跳转
    navigateTo:              navigate.navigateTo,
    // 关闭当前页面,并进行页面跳转
    redirectTo:              navigate.redirectTo,
    // 并关闭所有页面,并进行页面跳转
    reLaunch:                navigate.reLaunch,
    // 并关闭所有非tab页面,并进行tab面跳转
    switchTab:               navigate.switchTab,
    // 页面返回
    navigateBack:            navigate.navigateBack,
    // 跳转到首页
    navigateToHome:          navigate.navigateToHome,
    // 跳转到登录页
    navigateToLogin:         navigate.navigateToLogin,
    // 跳转到小程序
    navigateToMiniProgram:   navigate.navigateToMiniProgram,
    // 触发全局的自定义事件，附加参数都会传给监听器回调函数。
    $emit:                   navigate.$emit,
    // 监听全局的自定义事件，事件由 uni.$emit 触发，回调函数会接收事件触发函数的传入参数。
    $on:                     navigate.$on,
    // 触发全局的自定义事件，附加参数都会传给监听器回调函数。
    $once:                   navigate.$once,
    // 移除全局自定义事件监听器。
    $off:                    navigate.$off, 
    pubfn:{
		checkLogin : function(obj = {}) {
			let vk = uni.vk;
			let loginUrl = vk.getConfig("login.url");
			try {
				let url;
				try {
					url = obj.url || vk.pubfn.getCurrentPageRoute();
				} catch (err) {
					url = vk.getConfig("index.url") || "/pages/index/index";
				}
				vk.navigate.checkNeedLogin({
					url: url,
					success: function(res) {
						if (res.needLogin) {
							// 记录下原本要跳转的页面
							url = vk.pubfn.getPageFullPath(obj.fullPath || url);
							vk.navigate.setOriginalPage({ url });
							if (obj.isOnLaunch) vk.navigate.isOnLaunchToLogin = true; // 标记为首次启动的页面需要登录
							uni.reLaunch({
								url: loginUrl,
								success: () => {
									// #ifdef MP-WEIXIN
									setTimeout(() => {
										uni.hideHomeButton();
									}, 400);
									// #endif
								}
							});
						} else {
							// #ifdef H5
							// 解决微信公众号登录无法跳回原页面的问题
							if (!obj.options || !obj.options.code || !obj.options.state) {
								vk.navigate.setOriginalPage(null);
							}
							// #endif
							// #ifndef H5
							vk.navigate.setOriginalPage(null);
							// #endif
						}
					}
				});
			} catch (err) {
				console.error("catch", err);
				uni.reLaunch({
					url: loginUrl
				});
				// #ifdef MP-WEIXIN
				uni.hideHomeButton();
				// #endif
			}
		},
		getCurrentPageRoute : function(removeSlash) {
			let pages = getCurrentPages();
			let page = pages[pages.length - 1];
			if (removeSlash) {
				return page.route;
			} else {
				return "/" + page.route;
			}
		},
		getCurrentPage:function() {
			let res = {};
			let pages = getCurrentPages();
			let page = pages[pages.length - 1];
			if (page.route.indexOf("/") == 0) page.route = page.route.substring(1);
			let pagePath = `/${page.route}`;
			let fullPath = `/${page.route}`;
			let options = page.options;
			if (page.$page) {
				if (typeof page.$page.fullPath !== "undefined") {
					fullPath = page.$page.fullPath;
				} else if (typeof options === "object") {
					let optionsStr = vk.pubfn.queryParams(options);
					fullPath = pagePath + optionsStr;
				}
			}
			res.fullPath = fullPath;
			res.pagePath = pagePath;
			res.options = options;
			res.route = page.route;
			res.$vm = page.$vm;
			return res;
		},
        copyObject:function(obj){
            if (typeof obj !== "undefined") {
            	return JSON.parse(JSON.stringify(obj));
            } else {
            	return obj;
            }
        },
        getData:function(dataObj, name, defaultValue) {
            let newDataObj;
            if (vk.pubfn.isNotNull(dataObj)) {
                newDataObj = JSON.parse(JSON.stringify(dataObj));
                let k = "",
                    d = ".",
                    l = "[",
                    r = "]";
                name = name.replace(/\s+/g, k) + d;
                let tstr = k;
                for (let i = 0; i < name.length; i++) {
                    let theChar = name.charAt(i);
                    if (theChar != d && theChar != l && theChar != r) {
                        tstr += theChar;
                    } else if (newDataObj) {
                        if (tstr != k) newDataObj = newDataObj[tstr];
                        tstr = k;
                    }
                }
            }
            if (typeof newDataObj === "undefined" && typeof defaultValue !== "undefined") newDataObj = defaultValue;
            return newDataObj;
        },
        isNull:function(value) {
        	let key = false;
        	if (
        		typeof value == "undefined" ||
        		Object.prototype.toString.call(value) == "[object Null]" ||
        		JSON.stringify(value) == "{}" ||
        		JSON.stringify(value) == "[]" ||
        		value === "" ||
        		JSON.stringify(value) === undefined
        	) {
        		key = true;
        	}
        	return key;
        },
        isNotNull:function(value){
            return !vk.pubfn.isNull(value);
        },
        timeFormat:function(date, fmt = 'yyyy-MM-dd hh:mm:ss', targetTimezone) {
            try {
                if (!date) return "";
                targetTimezone = util.getTargetTimezone(targetTimezone);
                let nowDate = util.getTimeByTimeZone(date, targetTimezone);
                let opt = {
                    "M+": nowDate.getMonth() + 1, //月份
                    "d+": nowDate.getDate(), //日
                    "h+": nowDate.getHours(), //小时
                    "m+": nowDate.getMinutes(), //分
                    "s+": nowDate.getSeconds(), //秒
                    "q+": Math.floor((nowDate.getMonth() + 3) / 3), //季度
                    "S": nowDate.getMilliseconds(), //毫秒
                    "Z": `${targetTimezone >= 0 ? '+' : '-'}${Math.abs(targetTimezone).toString().padStart(2, '0')}:00` // 时区
                };
                let regex = new RegExp("(y+)");
                if (regex.test(fmt)) {
                    let fmtMatch = fmt.match(regex);
                    fmt = fmt.replace(fmtMatch[1], (nowDate.getFullYear() + "").substr(4 - fmtMatch[1].length));
                }
                for (let k in opt) {
                    let regex = new RegExp("(" + k + ")");
                    if (regex.test(fmt)) {
                        let fmtMatch = fmt.match(regex);
                        fmt = fmt.replace(fmtMatch[1], (fmtMatch[1].length == 1) ? (opt[k]) : (("00" + opt[k]).substr(("" + opt[k]).length)));
                    }
                }
                return fmt;
            } catch (err) {
                // 若格式错误,则原值显示
                return date;
            }
        },
        getPageFullPath :function(url) {
        	let fullPath = url;
        	if (fullPath.indexOf("/") !== 0) {
        		if (fullPath.indexOf("./") === 0) {
        			//fullPath = "." + fullPath;
        			fullPath = fullPath.substring(2);
        		}
        		let urlSplit = fullPath.split("../");
        		// 向上目录级数,0:根目录 1:向上1级
        		let level = urlSplit.length;
        		// 尾部路径
        		let urlEnd = urlSplit[level - 1];
        		// 获取当前页面的页面全路径
        		let pages = getCurrentPages();
        		let currentPage = pages[pages.length - 1];
        		let currentPagePath = currentPage.route;
        		// 分割成目录,最后一段是页面名称
        		let urlArr = currentPagePath.split("/");
        		let urlSplicing = "";
        		// 开始拼接
        		for (let i = 0; i < urlArr.length - level; i++) {
        			urlSplicing += urlArr[i] + "/";
        		}
        		// 完整页面路径
        		fullPath = urlSplicing + urlEnd;
        		if (fullPath.indexOf("/") != 0) {
        			fullPath = "/" + fullPath;
        		}
        	}
        	return fullPath;
        }
        
    }, 
    alert:             modal.alert,
    toast:             modal.toast,
    confirm:           modal.confirm,
    prompt:            modal.prompt,
    showActionSheet:   modal.showActionSheet,
    showLoading:       modal.showLoading,
    hideLoading:       modal.hideLoading,
    setLoading:        modal.setLoading
}
vk.init = function(obj = {}) {
	let {
		Vue, // Vue实例
		config // 配置
	} = obj;
	Vue.mixin(storeMixin);
	// 自定义云函数路由配置
	vk.callFunctionUtil.setConfig(config); 
};

vk.getGlobalObject = function() {
	if (typeof globalThis === "object") return globalThis;
	if (typeof self === "object") return self;
	if (typeof window === "object") return window;
	if (typeof global === "object") return global;
};
// 加载拓展功能
vk.use = function(obj, util) {
	for (let name in obj) {
		if (obj[name] && typeof obj[name].init === "function") {
			obj[name].init(util);
		}
		vk[name] = obj[name];
	}
};

const install = (Vue, config) => {
	 
	// #ifndef VUE3
	 
	Vue.prototype.vk = vk;
	Vue.prototype.$fn = vk.pubfn;

	// #endif

	// #ifdef VUE3
	// 将vk挂载到Vue实例
	Vue.config.globalProperties.vk = vk;
	Vue.config.globalProperties.$fn = vk.pubfn;
	// #endif

	// 将vk挂载到uni对象
	if (typeof uni == "object") uni.vk = vk;
	// 将vk挂载到全局
	let vkGlobalThis = vk.getGlobalObject();
	if (typeof vkGlobalThis == "object") vkGlobalThis.vk = vk;
	let util = { vk };
	vk.use({
		callFunctionUtil: vk.callFunctionUtil 
	}, util);  
	// 初始化并加载vk配置
	if (config) {
		vk.init({
			Vue,               // Vue实例
			config,	           // 配置
		});
	}
}

export default {
	install
} 